

#ifndef _MY_STRING_CLASS_H_
#define _MY_STRING_CLASS_H_

#include "Allocater.h"

#include <stdarg.h>
/*
#ifndef _WCHAR_T_DEFINED
typedef unsigned short wchar_t;
#endif //_WCHAR_T_DEFINED
*/


class String
{
private:
	typedef char E;
public:

	//-----------------------------------------------------------------------------
	//	Types

	typedef HeapAllocator<E>									allocator_type;
    typedef E													value_type;

    typedef allocator_type::size_type							size_type;
    typedef allocator_type::difference_type						difference_type;

    typedef allocator_type::reference							reference;
    typedef allocator_type::const_reference						const_reference;
    typedef allocator_type::pointer								pointer;
    typedef allocator_type::const_pointer						const_pointer;

    typedef allocator_type::pointer								iterator;
    typedef allocator_type::const_pointer						const_iterator;

/*
#ifdef _MSC_VER
    // broken templates in VC++
    typedef std::reverse_iterator<const_iterator, value_type,
                    const_reference, difference_type>			const_reverse_iterator;
    typedef std::reverse_iterator<iterator, value_type,
                    reference, difference_type>					reverse_iterator;
#else
    typedef std::reverse_iterator<const_iterator> 				const_reverse_iterator;
    typedef std::reverse_iterator<iterator>                     reverse_iterator;
#endif
*/
	//-----------------------------------------------------------------------------
	//	Case sensitivity statics.
	//	The function increments the state, so if you set 'true' twice, then
	//	you must set 'false' twice as well.
	//	Note: it only effects compare functions and the comparison operators
	//	it does not effect the find and rfind functions

	// set case sensitivity (true means make case sensitive)
	static inline bool		caseSensitive(bool sens);

	// returns true if string behaves case sensitive
	static inline bool		caseSensitive();


	//-----------------------------------------------------------------------------
	//	Construction

    inline	 		String();

    inline	 		String( const String& s );
					String( const String& s, size_t pos, size_t n = npos );

    				String( const char* s, size_t pos, size_t n );
    				String( const char* s, size_t n = npos );

    inline			String( size_t n, char c );
    inline			String( const_iterator first, const_iterator last);

	inline			~String();

    inline String&	operator = ( const String& s );
    inline String&	operator = ( const char *s );

	//-----------------------------------------------------------------------------
	//	Iterators

    inline iterator		begin();
    inline const_iterator	begin() const;
    inline iterator		end();
    inline const_iterator	end() const;

/*
    inline reverse_iterator		rbegin();
    inline const_reverse_iterator	rbegin() const;
    inline reverse_iterator		rend();
    inline const_reverse_iterator	rend() const;
*/
	//-----------------------------------------------------------------------------
	//	Misc

    inline const char*	c_str () const;
    inline const char*	data () const;

    inline 	size_t		length () const;
    inline 	size_t		size () const;
    inline 	size_t		max_size () const;
	inline	size_t		buf_size() const { return size()*sizeof(value_type); }

    		void		resize (size_t n, char c);
    inline 	void		resize (size_t n);
    inline 	size_t		capacity () const;
    inline 	void		reserve (size_t n = 0);
    inline 	bool		empty () const;

			void		to_upper ();	// convert string to upper case
			void		to_lower ();	// convert string to lower case

	// get sub-string list in token seperated string, return number of substrings
//			size_t		split_by_tokens(const String& tok, std::vector<String>& vec) const;

			// generate hash value for string
			uint32		hash() const;

			// calculate checksum of string
			uint32		checksum() const;

    inline 	char		operator[] (size_t pos) const;
    inline 	char&		operator[] (size_t pos);
    inline 	char		at (size_t pos) const;
    inline 	char&		at (size_t pos);

    inline 	char		front () const;
    inline 	char&		front ();

    inline 	char		back () const;
    inline 	char&		back ();

    inline 	String&		operator += (const String& s);
    inline 	String&		operator += (const char* s);
    inline 	String&		operator += (char c);

	// assign text with printf specifiers
	int	_cdecl			vprintf(const char *format, va_list argptr ); 
	int	_cdecl			printf(const char* format, ...);

	static const String& _cdecl sprintf(const char* format, ...);

	// scan using scanf
	int	_cdecl			vscanf(const char *format, va_list argptr ); 
	int	_cdecl			scanf(const char* format, ...);

	// conversion
	class String		unicode() const;

	//-----------------------------------------------------------------------------
	//	append()

    inline 	String&	append (const String& s);
    		String&	append (const String& s, size_t pos, size_t n);

    inline 	String&	append (const char* s, size_t n);
    inline 	String&	append (const char* s);

    inline 	String&	append (size_t n, char c);
    inline 	String&	append (char c);

    inline 	String&	append (const_iterator first, const_iterator last);

	//-----------------------------------------------------------------------------
	//	assign()

    		String&	assign (const String& s);
    		String&	assign (const String& s, size_t pos, size_t n);

    inline 	String&	assign (const char* s, size_t n);
    inline 	String&	assign (const char* s);

    inline 	String&	assign (size_t n, char c);
    inline 	String&	assign (char c);

    inline 	String&	assign (const_iterator first, const_iterator last);

	//-----------------------------------------------------------------------------
	//	insert()

    inline 	String&	insert (size_t p0, const String& s);
    		String&	insert (size_t p0, const String& s, size_t pos, size_t n);

    inline 	String&	insert (size_t p0, const char* s, size_t n);
    inline 	String&	insert (size_t p0, const char* s);

    inline 	String&	insert (size_t p0, size_t n, char c);
    inline 	String&	insert (size_t p0, char c);

    inline iterator	insert (iterator it, size_t n, char c);
    inline iterator	insert (iterator it, char c);

    inline void		insert (iterator it, const_iterator first, const_iterator last);

	//-----------------------------------------------------------------------------
	//	remove()

    inline String&	remove (size_t pos = 0, size_t n = npos);
    inline String&	remove (iterator);
    inline String&	remove (iterator, iterator);

	//-----------------------------------------------------------------------------
	//	erase()

    inline String&	erase (size_t p0 = 0, size_t n = npos);
    inline iterator	erase (iterator it);
    inline iterator	erase (iterator first, iterator last);

	inline void		clear ();

	//-----------------------------------------------------------------------------
	//	replace()

    inline 	String&	replace (size_t p0, size_t n0, const String& s);
    inline	String&	replace (size_t p0, size_t n0, const String& s, size_t pos, size_t n);

    inline 	String&	replace (size_t p0, size_t n0, const char* s, size_t n);
    inline 	String&	replace (size_t p0, size_t n0, const char* s);

    inline 	String&	replace (size_t p0, size_t n0, size_t n, char c);

    inline 	String&	replace (iterator first0, iterator last0, const String& s);

    inline 	String&	replace (iterator first0, iterator last0, const char* s, size_t n);
    inline 	String&	replace (iterator first0, iterator last0, const char* s);

    inline 	String&	replace (iterator first0, iterator last0, size_t n, char c);
    inline 	String&	replace (iterator first0, iterator last0, char c);

    inline 	String&	replace (iterator first0, iterator last0, 
							const_iterator first, const_iterator last);

    		size_t	copy (char* s, size_t n, size_t pos = 0);
    inline 	String	copy () const; 

    inline 	void	swap (String& s);

	//-----------------------------------------------------------------------------
	//	find functions

    		size_t		find (const String& s, size_t pos = 0) const;
    inline 	size_t		find (const char* s, size_t pos, size_t n) const;
    inline 	size_t		find (const char*, size_t pos = 0) const;
    inline 	size_t		find (char c, size_t pos = 0) const;

    		size_t		rfind (const String& s, size_t pos = npos) const;
    inline 	size_t		rfind (const char* s, size_t pos, size_t n) const;
    inline 	size_t		rfind (const char* s, size_t pos = npos) const;
    inline 	size_t		rfind (char, size_t pos = npos) const;

    		size_t		find_first_of (const String& s, size_t pos = 0) const;
    inline 	size_t		find_first_of (const char* s, size_t pos, size_t n) const;
    inline 	size_t		find_first_of (const char* s, size_t pos = 0) const;
    inline 	size_t		find_first_of (char c, size_t pos = 0) const;

    		size_t		find_last_of (const String& s, size_t pos = npos) const;
    inline 	size_t		find_last_of (const char* s, size_t pos, size_t n) const;
    inline 	size_t		find_last_of (const char* s, size_t pos = npos) const;
    inline 	size_t		find_last_of (char c, size_t pos = npos) const;

    		size_t		find_first_not_of (const String& s, size_t pos = 0) const;
    inline 	size_t		find_first_not_of (const char* s, size_t pos, size_t n) const;
    inline 	size_t		find_first_not_of (const char* s, size_t pos = 0) const;
    inline 	size_t		find_first_not_of (char c, size_t pos = 0) const;

    		size_t		find_last_not_of (const String& s, size_t pos = npos) const;
    inline 	size_t		find_last_not_of (const char* s, size_t pos, size_t n) const;
    inline 	size_t		find_last_not_of (const char* s, size_t pos = npos) const;
    inline 	size_t		find_last_not_of (char c, size_t pos = npos) const;

    		String		substr (size_t pos = 0, size_t n = npos) const;

	//-----------------------------------------------------------------------------`
	// find_replace_all()
	void				find_replace_all( const String& pattern, const String& replace );

	//-----------------------------------------------------------------------------
	//	compare()

    inline 	int			compare (const String& s) const;
    inline 	int			compare (const String& s, size_t pos, size_t n = npos) const;

    inline 	int			compare (size_t p0, size_t n0, const String& s) const;
    		int			compare (size_t p0, size_t n0, const String& s, size_t pos, size_t n = npos) const;

    inline 	int			compare (const char* s) const;
    inline 	int			compare (size_t p0, size_t n0, const char* s) const;
    inline 	int			compare (size_t p0, size_t n0, const char* s, size_t pos, size_t n = npos) const;

	//-----------------------------------------------------------------------------
	//	compare() - insensistive

    inline 	int			icompare (const String& s) const;
    inline 	int			icompare (const String& s, size_t pos, size_t n = npos) const;

    inline 	int			icompare (size_t p0, size_t n0, const String& s) const;
    inline	int			icompare (size_t p0, size_t n0, const String& s, size_t pos, size_t n = npos) const;

    inline 	int			icompare (const char* s) const;
    inline 	int			icompare (size_t p0, size_t n0, const char* s) const;
    inline 	int			icompare (size_t p0, size_t n0, const char* s, size_t pos, size_t n = npos) const;


protected:

	//-----------------------------------------------------------------------------
	//	StringRef, stores actual strings data

	class StringRef
	{
	public:
		inline size_t		length () const;
		inline void			set_length (size_t);
		inline size_t		capacity () const;
		inline size_t		ref_count () const;
		inline char*		data ()	const;

		inline void			add_ref ();
		inline void			release ();

		inline void			init(size_t cap, size_t sz);

	private:
		size_t		_ref_count;
		size_t		_capacity;
		size_t		_size;
	};

	struct NullStringRef
	{
		size_t		_ref_count;
		size_t		_capacity;
		size_t		_size;
		char		eos;
	};

	//-----------------------------------------------------------------------------
	//	protected members

    inline StringRef* ref () const;
	inline StringRef* get_null_ref() const;

    inline 	void	cow ();
    inline 	void	cow (size_t nc);
			void	clone ();
			void	clone (size_t nc);

	inline 	char*	make_null_ref () const;
			char*	make_ref (size_t capacity, size_t size) const;
			char*	make_ref (size_t capacity, size_t size, const char* dat) const;
			char*	make_ref (size_t capacity, size_t size, char c) const;

	inline void		set_data (char* dat);

    iterator		replace_it (size_t p0, size_t n0, const String& s, size_t pos, size_t n);

    static char eos() { return '\0'; }

	char*		_data;

    static NullStringRef	null_string;

public:
	// constant value which commonly represents end of string, or find failure.
    static const size_type npos;
	static int		nCaseSensitive;		// >0 case sensitive, <=0 not

};



//------------------------------------------------------------------------------
//
//	Inlines of String class
//
//------------------------------------------------------------------------------

// push case sensitivity (true means make case sensitive)
inline bool String::caseSensitive(bool sens)
{	
	if (sens) 
		nCaseSensitive++; 
	else 
		nCaseSensitive--; 

	return nCaseSensitive > 0;
}

// returns true if string behaves case sensitive
inline bool String::caseSensitive()
{	return nCaseSensitive > 0; }

inline String::String ()
{	_data = make_null_ref(); }

inline String::String( const String& s )
{	_data = s._data; ref()->add_ref(); }

inline String::String(size_t n, char c)
{	_data = make_ref(n,n, c); }

inline String::String( const_iterator first, const_iterator last)
{	
	size_t sz = last-first; 
	_data = make_ref(sz,sz,first); 
}

inline String::~String ()
{	ref()->release(); }

inline String::iterator String::begin()
{	cow(); return _data; }

inline String::const_iterator String::begin() const
{	return _data; }

inline String::iterator String::end()
{	cow(); return _data + length(); }

inline String::const_iterator String::end() const
{	return _data + length(); }

/*
inline String::reverse_iterator String::rbegin()
{	cow(); return reverse_iterator (end()); }

inline String::const_reverse_iterator String::rbegin() const
{	return const_reverse_iterator(end()); }

inline String::reverse_iterator String::rend()
{	cow(); return reverse_iterator(begin()); }

inline String::const_reverse_iterator String::rend () const
{ 	return const_reverse_iterator(begin()); }
*/

inline String& String::operator += (const String& s)
{	return append(s); }

inline String& String::operator += (const char* s)
{	return append(s); }

inline String& String::operator += (char c)
{	return append((size_t) 1, c); }

inline String& String::operator = (const char* s)
{	return assign(s); }

inline String& String::operator = (const String& s)
{	return assign(s); }

inline String& String::append (char c)
{	return append(1,c); }

inline String& String::append (const String& s)
{	return append(s,0,s.length()); }

inline String& String::append (const char* s, size_t n)
{	return append(String(s,n)); }

inline String& String::append (const char* s)
{	return append(String(s)); }

inline String& String::append (size_t n, char c)
{	return append(String(n,c)); }

inline String& String::append (const_iterator first, const_iterator last)
{	return append(String(first, last)); }

inline String& String::assign (const char* s, size_t n)
{	return assign(String(s,n)); }

inline String& String::assign (const char* s)
{	return assign(String(s)); }

inline String& String::assign (char c)
{	return assign(1,c); }

inline String& String::assign (size_t n, char c)
{	return assign(String(n,c)); }

inline String& String::assign (const_iterator first, const_iterator last)
{	return assign(String(first, last)); }

inline String& String::insert (size_t p0, const String& s)
{	return insert(p0,s,0,npos); }

inline String& String::insert (size_t pos, const char* s, size_t n)
{	return insert(pos, String(s,n)); }

inline String& String::insert (size_t pos, const char* s)
{	return insert(pos, String(s)); }

inline String& String::insert (size_t p0, char c)
{	return insert(p0,1,c); }

inline String::iterator String::insert (iterator it, char c)
{	return insert(it,1,c); }

inline String& String::insert(size_t pos, size_t n, char c)
{	return insert(pos, String(n,c)); }

inline String::iterator String::insert (iterator p, size_t n, char c)
{	String temp(n,c);
	return replace_it(p-begin(),0, temp, 0, npos); 
}

inline void String::insert (iterator p, const_iterator first, const_iterator last)
{	replace(p-begin(), 0, String(first, last)); }

inline String& String::erase (size_t p0, size_t n) 
{	return replace(p0, min(n, length() - p0), String(0, (char)0), 0,0); }

inline String::iterator String::erase (iterator it) 
{	return replace_it(it - begin(), 1, String(0, (char)0), 0,0); }

inline String::iterator String::erase (iterator first, iterator last) 
{	return replace_it(first-begin(),last-first, String(0, (char)0), 0,0); }

inline String& String::remove (size_t pos, size_t n)
{	return replace(pos, min(n, length() - pos), String(0, (char)0)); }

inline String& String::remove (iterator it)
{	return replace(it - begin(), 1, String(0, (char)0)); }

inline String& String::remove (iterator first, iterator last)
{	return replace(first-begin(), min(last - first, end() - first), 
								String(0, (char)0));
}

inline String& String::replace (size_t p0, size_t n0, const String& s, 
									size_t pos, size_t n)
{	replace_it(p0, n0, s, pos, n); return *this; }

inline String& String::replace (size_t p0, size_t n0, const String& s)
{	return replace(p0, n0, s, 0, s.length()); }

inline String& String::replace (iterator first0, iterator last0, char c)
{	return replace(first0,last0,1,c); }

inline String& String::replace (size_t p0, size_t n0, const char* s, size_t n)
{	return replace(p0, n0, String(s,n)); }

inline String& String::replace (size_t p0, size_t n0, const char* s)
{	return replace(p0, n0, String(s)); }

inline String& String::replace (size_t p0, size_t n0, size_t n, char c)
{	return replace(p0, n0, String(n,c)); }

inline String& String::replace (iterator first0, iterator last0,
										const String& s)
{	return replace(first0 - begin(), last0 - first0, s); }

inline String& String::replace (iterator first0, iterator last0,
										const char* s, size_t n)
{	return replace(first0,last0,String(s,n)); }

inline String& String::replace (iterator first0, iterator last0,
										const char* s)
{	return replace(first0,last0,String(s)); }

inline String& String::replace (iterator first0, iterator last0,
										size_t n, char c)
{	return replace(first0,last0,String(n,c)); }

inline String& String::replace (iterator first0, iterator last0,
										const_iterator first, const_iterator last)
{	return replace(first0,last0, String(first,last)); }

inline char String::operator[] (size_t pos) const
{	return pos == size() ? eos() : _data[pos]; }

inline char& String::operator[] (size_t pos)
{	cow(); return _data[pos]; }

inline char String::at (size_t pos) const
{	return _data[pos]; }

inline char& String::at (size_t pos)
{	return _data[pos]; }

inline char String::front () const
{	return _data[0]; }

inline char& String::front ()
{	return _data[0]; }

inline char String::back () const
{	return _data[length()-1]; }

inline char& String::back ()
{	return _data[length()-1]; }

inline const char* String::c_str () const
{	return _data; }

inline const char* String::data () const
{	return length() == 0 ? 0 : _data; }

inline size_t String::length () const
{	return ref()->length(); }

inline size_t String::size() const		
{	return length(); }

inline size_t String::max_size() const
{	return npos - sizeof(StringRef); }

inline void String::resize (size_t n)
{	resize(n, eos()); }

inline void String::clear ()
{	resize( 0 ); }

inline size_t String::capacity () const
{	return ref()->capacity(); }

inline void String::reserve(size_t n)
{	if (n > capacity()) clone(n); }

inline bool	String::empty() const
{	return length() == 0; }

inline void String::swap(String& s)
{	::swap( s._data, _data ); }

inline String String::copy () const
{	String temp(*this);  temp.clone();  return temp; }

inline size_t String::find (const char* s, size_t pos, size_t n) const
{	return find(String(s, n), pos); }

inline size_t String::find (const char* s, size_t pos) const
{	return find(String(s), pos); }

inline size_t String::find (char c, size_t pos) const
{	return find(String(1, c), pos); }

inline size_t String::rfind (const char* s, size_t pos, size_t n) const
{	return rfind(String(s,n), pos); }

inline size_t String::rfind (const char* s, size_t pos) const
{	return rfind(String(s), pos); }

inline size_t String::rfind (char c, size_t pos) const
{	return rfind(String(1, c), pos); }

inline size_t String::find_first_of (const char* s, size_t pos, size_t n) const
{	return find_first_of(String(s, n), pos); }

inline size_t String::find_first_of (const char* s, size_t pos) const
{	return find_first_of(String(s), pos); }

inline size_t String::find_first_of (char c, size_t pos) const
{	return find_first_of(String(1, c), pos); }

inline size_t String::find_last_of (const char* s, size_t pos, size_t n) const
{	return find_last_of(String(s,n), pos); }

inline size_t String::find_last_of (const char* s, size_t pos) const
{	return find_last_of(String(s), pos); }

inline size_t String::find_last_of (char c, size_t pos) const
{	return find_last_of(String(1, c), pos); }

inline size_t String::find_first_not_of (const char* s, size_t pos, size_t n) const
{	return find_first_not_of(String(s, n), pos); }

inline size_t String::find_first_not_of (const char* s, size_t pos) const
{	return find_first_not_of(String(s), pos); }

inline size_t String::find_first_not_of (char c, size_t pos) const
{	return find_first_not_of(String(1, c), pos); }

inline size_t String::find_last_not_of(const char* s, size_t pos, size_t n) const
{	return find_last_not_of(String(s,n), pos); }

inline size_t String::find_last_not_of (const char* s, size_t pos) const
{	return find_last_not_of(String(s), pos); }

inline size_t String::find_last_not_of (char c, size_t pos) const
{	return find_last_not_of(String(1, c), pos); }

inline int String::compare (const String& s, size_t pos, size_t n) const
{	return compare(0,length(),s,pos,n); }

inline int String::compare (const String& s) const
{	
	if (_data == s._data) 
		return 0;
	else
		return compare(s,0,s.length()); 
}

inline int String::compare (size_t p0, size_t n0, const String& s) const
{	return compare(p0,n0,s,0,s.length()); }

inline int String::compare (const char* s) const
{	return compare(String(s)); }

inline int String::compare (size_t p0, size_t n0, const char* s) const
{	return compare(p0,n0,String(s)); }

inline int String::compare (size_t p0, size_t n0, const char* s, size_t pos, size_t n) const
{	return compare(p0,n0,String(s),pos,n); }


inline int String::icompare (size_t p0, size_t n0, const String& s, size_t pos, size_t n) const
{	caseSensitive(false); 
	int b = compare(p0,n0,s,pos,n); 
	caseSensitive(true);  
	return b; 
}

inline int String::icompare (const String& s, size_t pos, size_t n) const
{	return icompare(0,length(),s,pos,n); }

inline int String::icompare (const String& s) const
{	return icompare(s,0,s.length()); }

inline int String::icompare (size_t p0, size_t n0, const String& s) const
{	return icompare(p0,n0,s,0,s.length()); }

inline int String::icompare (const char* s) const
{	return icompare(String(s)); }

inline int String::icompare (size_t p0, size_t n0, const char* s) const
{	return icompare(p0,n0,String(s)); }

inline int String::icompare (size_t p0, size_t n0, const char* s, size_t pos, size_t n) const
{	return icompare(p0,n0,String(s),pos,n); }


//-----------------------------------------------------------------------------
//	Non-member Inlines
//-----------------------------------------------------------------------------

inline String operator + ( const String& lhs, const String& rhs)
{	return String(lhs).append(rhs); }

inline String operator + ( const char* lhs, const String& rhs)
{	return String(lhs).append(rhs); }

inline String operator + ( char lhs, const String& rhs)
{	return String(1,lhs).append(rhs); }

inline String operator + ( const String& lhs, const char* rhs)
{	return String(lhs).append(String(rhs)); }

inline String operator + (const String& lhs, char rhs)
{	return String(lhs).append(String(1,rhs)); }

inline bool operator == ( const String& lhs, const String& rhs)
{	return lhs.compare(rhs) == 0; }

inline bool operator == ( const char* lhs, const String& rhs)
{	return String(lhs).compare(rhs) == 0; }

inline bool operator == ( const String& lhs, const char* rhs)
{	return lhs.compare(String(rhs)) == 0; }

inline bool operator < ( const String& lhs, const String& rhs)
{	return lhs.compare(rhs) < 0; }

inline bool operator < ( const char* lhs, const String& rhs)
{	return String(lhs).compare(rhs) < 0; }

inline bool operator < ( const String& lhs, const char* rhs)
{	return lhs.compare(String(rhs)) < 0; }

inline bool operator != ( const String& lhs, const String& rhs)
{	return lhs.compare(rhs) != 0; }

inline bool operator != ( const char* lhs, const String& rhs)
{	return String(lhs).compare(rhs) != 0; }

inline bool operator != ( const String& lhs, const char* rhs)
{	return lhs.compare(String(rhs)) != 0; }

inline bool operator > ( const String& lhs, const String& rhs)
{	return lhs.compare(rhs) > 0; }

inline bool operator > (const char* lhs, const String& rhs)
{	return String(lhs).compare(rhs) > 0; }

inline bool operator > (const String& lhs, const char* rhs)
{	return lhs.compare(String(rhs)) > 0; }

inline bool operator <= (const String& lhs, const String& rhs)
{	return lhs.compare(rhs) <= 0; }

inline bool operator <= (const char* lhs, const String& rhs)
{	return String(lhs).compare(rhs) <= 0; }

inline bool operator <= (const String& lhs, const char* rhs)
{	return lhs.compare(String(rhs)) <= 0; }

inline bool operator >= (const String& lhs, const String& rhs)
{	return lhs.compare(rhs) >= 0; }

inline bool operator >= (const char* lhs, const String& rhs)
{	return String(lhs).compare(rhs) >= 0; }

inline bool operator >= (const String& lhs, const char* rhs)
{	return lhs.compare(String(rhs)) >= 0; }

//-----------------------------------------------------------------------------
//	String privates
//-----------------------------------------------------------------------------
inline String::StringRef* String::ref() const
{	return (StringRef*) (((StringRef*) _data) - 1); }

inline void String::cow ()
{	if (ref()->ref_count() > 1) clone(); }

inline void String::cow (size_t nc)
{	if (ref()->ref_count() > 1 || capacity() < nc) clone(nc); }

inline String::StringRef* String::get_null_ref () const
{	return (StringRef*)&null_string; }

inline char* String::make_null_ref () const
{	get_null_ref()->add_ref(); return get_null_ref()->data(); }

inline void String::set_data (char* dat)
{	ref()->release(); _data = dat; }


//-----------------------------------------------------------------------------
//	String ref Inlines
//-----------------------------------------------------------------------------

inline size_t String::StringRef::length() const	
{	return _size; }

inline void String::StringRef::set_length(size_t l)
{	_size = l; }

inline size_t String::StringRef::capacity() const	
{	return _capacity;}

inline size_t String::StringRef::ref_count() const	
{	return _ref_count; }

inline char* String::StringRef::data() const	
{	return (char*)(this+1); }

inline void String::StringRef::add_ref() 
{	++_ref_count; }

inline void String::StringRef::release()
{
	if (! (--_ref_count) )
		delete ((void*)this);
}

inline void String::StringRef::init(size_t cap, size_t sz)
{
	_capacity = cap;
	_size = sz;
	_ref_count = 1;
	data()[sz] = '\0'; 
}



#endif //_K_STRING_CLASS_H_